import math
import pandas as pd
from iFinDPy import *
import json
import Core.Gadget as Gadget
import Core.DataSeries as DataSeries
import Core.Global as Global
import datetime

def get_data(list, index):
    if list != None and len(list) > index:
        return list[index]
    else:
        return ''


def IFind_DailyQuote(symbol, instrument_type, datetime1, datetime2, logger=None):
    #
    instrumentType = instrument_type
    # name = symbol + "_Time_86400_Bar"
    # dataObjects = DataSeries.DataSeries(name)  # List Modified to DataSeries Object 2018-3-28
    dataObjects = []
    # ---Params---
    param = 'Interval:D,CPS:1,baseDate:1900-01-01,Currency:YSHB,fill:Previous'
    param2 = 'Interval:D,CPS:5,baseDate:1900-01-01,Currency:YSHB,fill:Previous'

    # ---Fields---
    fields = "open;high;low;close;volume;amount"
    fields2 = 'open;high;low;close'
    # fields = "open,high,low,close,adjfactor,volume,amt,oi,dealnum,turn,free_turn,trade_status,total_shares,free_float_shares"; // sec_name, industry_sw
    if instrumentType == "Future":
        fields = fields + ";openInterest"
        fields2 = None
    elif instrumentType == "Stock":
        fields = fields + ";transactionAmount;turnoverRatio;totalShares;floatSharesOfAShares"
        #transactionAmount;turnoverRatio;totalShares;transactionAmount 成交笔数;换手率;总股本（total_shares）(缺少adjfactor，free_turn，trade_status)
    elif instrumentType == "Index":
        fields = fields + ";turnoverRatio"#, free_turn, total_shares, free_float_shares
        fields2 = None
        #缺少amount,free_turn,total_shares, free_float_shares
    elif instrumentType == "MutualFund":
        fields = "netAssetValue;adjustedNAV;accumulatedNAV" #单位净值; 复权单位净值; 累计单位净值
        fields2 = None
        #;netAssetValue;adjustedNAV;accumulatedNAV 单位净值;复权单位净值;累计单位净值(nav表里没找到)
    elif instrumentType == "Option":
        fields = fields + ";openInterest"
        fields2 = None
        #openInterest;持仓量;（settle，ptmtradeday，ptmday，us_impliedvol表里没找到）
    elif instrumentType == "Bond":
        # 基于中债的：净价 全价 应计利息 TYM(收益率) 修正久期 剩余年限
        fields = fields + ",net_cnbd, dirty_cnbd, accruedinterest_cnbd, yield_cnbd, modidura_cnbd, matu_cnbd"
        param = "credibility=1"

    # ---Request Functions---
    data = THS_HistoryQuotes(symbol, fields, param, datetime1, datetime2, True)
    resjson = json.loads(str(data, 'utf-8'))
    resjson_b = None
    if fields2:
        data_b = THS_HistoryQuotes(symbol, fields2, param2, datetime1, datetime2, True)
        resjson_b = json.loads(str(data_b, 'utf-8'))
    #THS_HistoryQuotes('600000.SH','open;high;low;close;volume;amount','Interval:D,CPS:1,baseDate:1900-01-01,Currency:YSHB,fill:Previous','2019-12-15','2020-12-15',True)


    # ---Check---
    if resjson['errorcode'] != 0:

        print("Error " + symbol)
        print(resjson['errmsg'])
        # PlaySound()
        return None

    #dataRecvCount = len(resjson['tables'][0]['time'])
    # for d in data['tables'][0]['time']:
    #     dataRecvCount += len(d)
    # Global.WIND_DATA_RECVED += dataRecvCount
    # print("Total Recv Data ", Global.WIND_DATA_RECVED)
    count = len(resjson['tables'][0]['time'])
    for i in range(count):
        # 虽然返回了数据，但是数据为空
        if resjson['tables'][0]['time'][i] == None:
            continue

        #
        dataObject = {}
        # dataObject["DataSeries"] = name
        dataObject["Symbol"] = symbol
        # dataObject["Size"] = 86400
        # dataObject["Bar_Type"] = "Time"
        # dataObject["Values"] = {}

        # ---Process Dirty DateTime---
        datetime0 = datetime.datetime.strptime(resjson['tables'][0]['time'][i], "%Y-%m-%d")

        # ---Process Open DateTime---
        if instrumentType in ["Stock", "Index", "Option"]:
            dataObject["Open_DateTime"] = datetime0.strftime('%Y-%m-%d 09:30:00.000')
        elif instrumentType == "Future":
            dataObject["Open_DateTime"] = datetime0.strftime('%Y-%m-%d 09:00:00.000')

        # ---Process Closed Time---
        closingTime = time(15, 0, 0)
        datetime0 = datetime.datetime.combine(datetime0, closingTime)
        # dataObject["DateTime"] = datetime0.strftime('%Y-%m-%d 15:00:00.000')
        dataObject["DateTime"] = datetime0
        dataObject["Date"] = Gadget.ToDate(datetime0)
        sDateTime = dataObject["DateTime"].strftime('%Y-%m-%d 15:00:00.000')

        # dataObject["UTC_DateTime"] = Gadget.ToUTCDateTime(datetime0)
        dataObject["Key"] = symbol + "_Time_86400_Bar" + "_" + sDateTime

        #
        json_keys = list(resjson['tables'][0]['table'].keys())
        json_keys_b = None
        if resjson_b:
            json_keys_b = list(resjson_b['tables'][0]['table'].keys())

        # ---Common Fields---
        if "open" in json_keys:
            dataObject["Open"] = resjson['tables'][0]['table']['open'][i]
        if "high" in json_keys:
            dataObject["High"] = resjson['tables'][0]['table']['high'][i]
        if "low" in json_keys:
            dataObject["Low"] = resjson['tables'][0]['table']['low'][i]
        if "close" in json_keys:
            dataObject["Close"] = resjson['tables'][0]['table']['close'][i]
        if "volume" in json_keys:
            dataObject["Volume"] = resjson['tables'][0]['table']['volume'][i]
        if "amount" in json_keys:
            dataObject["Money"] = resjson['tables'][0]['table']['amount'][i]
        if "TRADE_STATUS" in json_keys:#缺少数据
            dataObject["Trade_Status"] = resjson['tables'][0]['table'][''][i]

        # ---Stock---
        #;transactionAmount;turnoverRatio;totalShares;floatSharesOfAShares  成交笔数;换手率;总股本;流通总股数；
        # elif field == "ADJFACTOR":#缺少数据
        #     dataObject["AdjFactor"] = resjson['tables'][0]['table'][iField][i]
        if "transactionAmount" in json_keys:
            dataObject["Deal_Number"] = resjson['tables'][0]['table']['transactionAmount'][i]
        if "turnoverRatio" in json_keys:
            dataObject["Turn"] = resjson['tables'][0]['table']['turnoverRatio'][i]
        # elif field == "FREE_TURN":#缺少数据
        #     dataObject["Free_Turn"] = resjson['tables'][0]['table'][iField][i]
        if "totalShares" in json_keys:
            dataObject["Total_Shares"] = resjson['tables'][0]['table']['totalShares'][i]
        if "floatSharesOfAShares" in json_keys:
            dataObject["Free_Float_Shares"] = resjson['tables'][0]['table']['floatSharesOfAShares'][i]
        if resjson_b:
            if 'open' in json_keys_b:
                dataObject["BOpen"] = get_data(resjson_b['tables'][0]['table']['open'],i)
            if 'high' in json_keys_b:
                dataObject["BHigh"] = resjson_b['tables'][0]['table']['high'][i]
            if 'low' in json_keys_b:
                dataObject["BLow"] = resjson_b['tables'][0]['table']['low'][i]
            if 'close' in json_keys_b:
                dataObject["BClose"] = resjson_b['tables'][0]['table']['close'][i]
            if 'close' in json_keys and 'close' in json_keys_b:
                dataObject["AdjFactor"] = resjson_b['tables'][0]['table']['close'][i]/resjson['tables'][0]['table']['close'][i]
        # # ---Future---
        if "openInterest" in json_keys:
            dataObject["Open_Int"] = resjson['tables'][0]['table']['openInterest'][i]
        #
        # # ---Fund---
        #netAssetValue,adjustedNAV,accumulatedNAV
        if 'netAssetValue' in json_keys:
            dataObject["Net_Asset_Value"] =resjson['tables'][0]['table']['netAssetValue'][i]
        if 'adjustedNAV' in json_keys:
            dataObject["Adjusted_Net_Asset_Value"] = resjson['tables'][0]['table']['adjustedNAV'][i]
        if "accumulatedNAV" in json_keys:
            dataObject["Accumulated_Net_Asset_Value"] = resjson['tables'][0]['table']['accumulatedNAV'][i]

        # ---Option---
        # elif field == "settle".upper():
        #     dataObject["Settlement"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "ptmtradeday".upper():
        #     dataObject["Trading_Days_Left"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "ptmday".upper():
        #     dataObject["Calender_Days_Left"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "us_impliedvol".upper():
        #     dataObject["Wind_Implied_Volatility"] = resjson['tables'][0]['table'][iField][i]

        # # ---Bond---
        # elif field == "net_cnbd".upper():
        #     dataObject["NetPriceCNBD"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "dirty_cnbd".upper():
        #     dataObject["DirtyPriceCNBD"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "accruedinterest_cnbd".upper():
        #     dataObject["AccruedInterestCNBD"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "yield_cnbd".upper():
        #     dataObject["YTMCNBD"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "modidura_cnbd".upper():
        #     dataObject["ModifiedDurationCNBD"] = resjson['tables'][0]['table'][iField][i]
        # elif field == "matu_cnbd".upper():
        #     dataObject["TermLeftCNBD"] = resjson['tables'][0]['table'][iField][i]

    # ---Invalid Data---
    # if "Close" in dataObject and (dataObject["Close"] == None or math.isnan(dataObject["Close"])):
    #
    #     continue
    #close为none情况
    #---For Stock Adjusted---



    # if instrumentType == "MutualFund":
    #     if dataObject["NAV_date"].date() < dataObject["DateTime"].date():
    #         continue
    #     del dataObject["NAV_date"]

    #
    # for k, v in dataObject.items():
    #     if not isinstance(v, float):
    #         continue
    #     if math.isnan(v):
    #         dataObject[k] = None
    #
        dataObjects.append(dataObject)
    return dataObjects


def IFind_History_Quote_MultiFields(symbol, datetime1, datetime2, fields=[], param=""):
    #
    if datetime2 == None:
        datetime2 = datetime1
    #
    s_datetime1 = datetime1.strftime('%Y-%m-%d')
    s_datetime2 = datetime2.strftime('%Y-%m-%d')

    #
    fields_number = len(fields)
    # data = w.wsd(symbol, fields, datetime1, datetime2, param)
    str_fields = ",".join(fields)
    #
    str_params = param + ",CPS:1,baseDate:1900-01-01,Currency:YSHB,fill:Previous"
    #
    resp = THS_HistoryQuotes(symbol,
                             str_fields,
                             str_params,
                             s_datetime1, s_datetime2,
                             True)
    #
    data = json.loads(str(resp, 'utf-8'))
    data = data["tables"][0]

    data_raw = []
    for i in range(len(data["time"])):
        entry = []
        for field in fields:
            entry.append(data["table"][field][i])
        data_raw.append(entry)

    df = pd.DataFrame(data=data_raw, index=data["time"], columns=fields)
    # print(df)
    return df


def Test_History_Quote_MultiFields():
    symbol = '801010.SL'
    fields = ["changeRatio", "pe_ttm_index", "volume"]
    param = "Interval:W"
    datetime1 = datetime.datetime(2020, 1, 1)
    datetime2 = datetime.datetime(2021, 1, 13)
    IFind_History_Quote_MultiFields(symbol, datetime1, datetime2, fields=fields, param=param)


if __name__ == '__main__':
    #
    from Core.Config import *
    pathfilename = os.getcwd() + "\..\Config\config_develop.json"
    config = Config(pathfilename)
    database = config.DataBase("JDMySQL")

    # a = THS_iFinDLogin('jd1098', '729251')
    a = THS_iFinDLogin('jd1079', '898132')
    print(a)

    #
    # Test_History_Quote_MultiFields()

    # test = THS_EDBQuery('M002859222', '', '2019-12-21', '2020-12-21')
    # res1 = IFind_DailyQuote('600000.SH','Stock','2019-12-15','2020-12-15')
    # res1 = IFind_DailyQuote('000001.OF', 'MutualFund', '2019-12-15', '2020-12-15')
    # res1 = IFind_DailyQuote('CU00.SHF', 'Future', '2019-12-15', '2020-12-15')
    # res1 = IFind_DailyQuote('10002477.SH', 'Option', '2019-12-15', '2020-12-15')
    # res1 = IFind_DailyQuote('AU8888.SHF', 'Index', '2020-01-04', '2021-01-04')
    res1 = IFind_DailyQuote('801811.SL', 'Index', '2020-01-04', '2021-01-04')

    # 补充指数
    index_list = ["801811.SI", "801812.SI", "801813.SI",
                  "801821.SI", "801822.SI", "801823.SI",
                  "801831.SI", "801832.SI", "801833.SI"]

    #print(res1)
    instrument_type = 'Index'#'Option'#'Future'#'MutualFund'#"Stock"
    # database.Upsert_Many("financial_data", instrument_type + "_dailybar2", {}, res1)
    #index_list = ['CN6112.SZ','000012.SH','H11001.CSI','000016.SH','000300.SH','000905.SH','AU8888.SHF','SPX.GI','HSI.GI']
